package com.ttscm.srds.utils;

import com.ttscm.srds.datagram.SeerDataPacket;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;

/**
 * @version:
 * @author:
 * @className:
 * @packageName:
 * @description:
 * @date: 2022/07/29
 */
public final class PacketUtil2 {
    public static byte[] marshalSeerPacket(long number, long type, String bodyDataArea) {
        byte[] dataAreaArray = new byte[0];

        // 封装数据包
        SeerDataPacket dataPacket = new SeerDataPacket();
        dataPacket.setHeaderSync(0x5A);
        dataPacket.setHeaderVersion(0x01);
        dataPacket.setHeaderReserved(0x000000000000);
        if (number < 0) {
            dataPacket.setHeaderNumber(0x00);
        } else {
            dataPacket.setHeaderNumber(number);
        }
        if (type < 0) {
            dataPacket.setHeaderType(0x03E8);
        } else {
            dataPacket.setHeaderType(type);
        }
        if (bodyDataArea == null || bodyDataArea.equals("")) {
            dataPacket.setHeaderLength(0x00000000);
        } else {
            dataPacket.setBodyDataArea(bodyDataArea);
            dataAreaArray = bodyDataArea.getBytes(StandardCharsets.US_ASCII);
            dataPacket.setHeaderLength(dataAreaArray.length);
        }

        // 转为字节数组 1（m_sync） + 1（m_version） + 2（m_number） + 4（m_length） + 2（m_type） + 6（m_reserved）=16
        // 头部
        byte[] dataHeaderArray = new byte[16];
        // 1（m_sync）
        dataHeaderArray[0] = (byte) dataPacket.getHeaderSync();
        // 1（m_version）
        dataHeaderArray[1] = (byte) dataPacket.getHeaderVersion();
        // 2（m_number）
        byte[] tempArray = BigInteger.valueOf(dataPacket.getHeaderNumber()).toByteArray();
        if (tempArray.length > 2) {
            System.arraycopy(tempArray, 1, dataHeaderArray, 2, 2);
        } else {
            int destPos = 3;
            for (int srcPos = tempArray.length - 1; srcPos >= 0; srcPos--) {
                System.arraycopy(tempArray, srcPos, dataHeaderArray, destPos--, 1);
            }
        }
        // 4（m_length）
        tempArray = BigInteger.valueOf(dataPacket.getHeaderLength()).toByteArray();
        if (tempArray.length > 4) {
            System.arraycopy(tempArray, 1, dataHeaderArray, 4, 4);
        } else {
            int destPos = 7;
            for (int srcPos = tempArray.length - 1; srcPos >= 0; srcPos--) {
                System.arraycopy(tempArray, srcPos, dataHeaderArray, destPos--, 1);
            }
        }
        // 2（m_type）
        tempArray = BigInteger.valueOf(dataPacket.getHeaderType()).toByteArray();
        if (tempArray.length > 2) {
            System.arraycopy(tempArray, 1, dataHeaderArray, 8, 2);
        } else {
            int destPos = 9;
            for (int srcPos = tempArray.length - 1; srcPos >= 0; srcPos--) {
                System.arraycopy(tempArray, srcPos, dataHeaderArray, destPos--, 1);
            }
        }
        //6（m_reserved） 全0

        // 无数据区
        if (dataPacket.getHeaderLength() <= 0) {
            return dataHeaderArray;
        }

        // 有数据区
        byte[] dataPacketArray = new byte[dataHeaderArray.length + dataAreaArray.length];
        System.arraycopy(dataHeaderArray, 0, dataPacketArray, 0, dataHeaderArray.length);
        System.arraycopy(dataAreaArray, 0, dataPacketArray, 16, dataAreaArray.length);
        return dataPacketArray;
    }

    public static SeerDataPacket unmarshalSeerPacket(byte[] dataPackets) {
        if (dataPackets == null) {
            return null;
        }
        if (dataPackets.length < 16) {
            return null;
        }

        SeerDataPacket dataPacket = new SeerDataPacket();

        byte[] temp = new byte[1];
        System.arraycopy(dataPackets, 0, temp, 0, temp.length);
        dataPacket.setHeaderSync(new BigInteger(1, temp).longValue());

        temp = new byte[1];
        System.arraycopy(dataPackets, 1, temp, 0, temp.length);
        dataPacket.setHeaderVersion(new BigInteger(1, temp).longValue());

        temp = new byte[2];
        System.arraycopy(dataPackets, 2, temp, 0, temp.length);
        dataPacket.setHeaderNumber(new BigInteger(1, temp).longValue());

        temp = new byte[4];
        System.arraycopy(dataPackets, 4, temp, 0, temp.length);
        dataPacket.setHeaderLength(new BigInteger(1, temp).longValue());

        temp = new byte[2];
        System.arraycopy(dataPackets, 8, temp, 0, temp.length);
        dataPacket.setHeaderType(new BigInteger(1, temp).longValue());

        temp = new byte[6];
        System.arraycopy(dataPackets, 10, temp, 0, temp.length);
        dataPacket.setHeaderReserved(new BigInteger(1, temp).longValue());

        // TODO 越界检查
        temp = new byte[(int) dataPacket.getHeaderLength()];
        System.arraycopy(dataPackets, 16, temp, 0, temp.length);
        dataPacket.setBodyDataArea(new String(temp, StandardCharsets.US_ASCII));

        return dataPacket;
    }

    public static String printPacketsHex(byte[] dataPackets) {
        // 打印
        StringBuilder dataPacketsLine = new StringBuilder();
        for (int i = 0; i < dataPackets.length; i++) {
            byte[] temp = new byte[1];
            System.arraycopy(dataPackets, i, temp, 0, 1);
            dataPacketsLine.append(" ").append(HexUtil.leadingZero(Long.toHexString(new BigInteger(1, temp).longValue()).toUpperCase(), 1));
        }

        return dataPacketsLine.toString();
    }

    public static String printPacketsHex2(byte[] dataPackets) {
        // 打印
        StringBuilder dataPacketsLine = new StringBuilder();
        byte[] temp = new byte[1];
        System.arraycopy(dataPackets, 0, temp, 0, 1);
        dataPacketsLine.append(HexUtil.leadingZero(Long.toHexString(new BigInteger(1, temp).longValue()).toUpperCase(), 1));

        temp = new byte[1];
        System.arraycopy(dataPackets, 1, temp, 0, 1);
        dataPacketsLine.append(HexUtil.leadingZero(Long.toHexString(new BigInteger(1, temp).longValue()).toUpperCase(), 1));

        temp = new byte[2];
        System.arraycopy(dataPackets, 2, temp, 0, 2);
        dataPacketsLine.append(HexUtil.leadingZero(Long.toHexString(new BigInteger(1, temp).longValue()).toUpperCase(), 2));

        temp = new byte[4];
        System.arraycopy(dataPackets, 4, temp, 0, 4);
        dataPacketsLine.append(HexUtil.leadingZero(Long.toHexString(new BigInteger(1, temp).longValue()).toUpperCase(), 4));

        temp = new byte[2];
        System.arraycopy(dataPackets, 8, temp, 0, 2);
        dataPacketsLine.append(HexUtil.leadingZero(Long.toHexString(new BigInteger(1, temp).longValue()).toUpperCase(), 2));

        temp = new byte[6];
        System.arraycopy(dataPackets, 10, temp, 0, 6);
        dataPacketsLine.append(HexUtil.leadingZero(Long.toHexString(new BigInteger(1, temp).longValue()).toUpperCase(), 6));

        return dataPacketsLine.toString();
    }
}
